﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using MethodWorx.CMS.Administration;
using MethodWorx.CMS.Configuration;
using MethodWorx.CMS.Plugins;
using MethodWorx.CMS.Providers;
using System.Web.Routing;
using MethodWorx.CMS.Services;
using MethodWorx.CMS.Content;

namespace MethodWorx.CMS.Web.Mvc
{
    public abstract class ContentController : Controller
    {
        private CmsRequestContext cmsRequestContext;
        private static ICmsDataProvider cmsDataProvider;

        /// <summary>
        /// The current request context
        /// </summary>
        protected CmsRequestContext CmsRequestContext
        {
            get { return this.cmsRequestContext;  }
        }   

        /// <summary>
        /// The current cms data provider
        /// </summary>
        protected ICmsDataProvider CmsDataProvider
        {
            get { return cmsDataProvider;  }
        }


        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            this.cmsRequestContext = this.GetCmsRequestContext();

            //
            //  ok, initialize it once
            if(cmsDataProvider == null)
                cmsDataProvider = this.GetCmsDataProvider();

            if(this.cmsRequestContext == null)
                throw new Exception("No CmsRequestContext available");

            if(cmsDataProvider == null)
                throw new Exception("No CmsDataProvider available");

            base.Initialize(requestContext);
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
          
            //
            //  ok, here we need to locate the correct page
            this.cmsRequestContext.Page = this.ResolvePageFromRequest(filterContext.RequestContext);
            this.cmsRequestContext.PreviewSession = this.GetPreviewSessionFromRequest(filterContext.RequestContext);



            base.OnActionExecuting(filterContext);
        }

        protected virtual Membership.PreviewSession GetPreviewSessionFromRequest(RequestContext requestContext)
        {
            if (requestContext.HttpContext.Request["preview"] != null)
            {
                var userService = new UserService(this.CmsDataProvider);

                var session = userService.GetPreviewSession(Guid.Parse(requestContext.HttpContext.Request["preview"]));
                return session;
            }

            return null;
        }

        protected virtual CMS.Content.Page ResolvePageFromRequest(RequestContext requestContext)
        {
            //
            //  ok, this is quite simple really
            //  split up the url and locate the page in the CMS, using regular expressions to match 
            //  get the service for accessing the content
            var service = new ContentService(this.CmsDataProvider);

            string[] parts = requestContext.HttpContext.Request.RawUrl.Split(new string[] { "?" }, 2, StringSplitOptions.None);
            string[] pages = parts[0].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
            var current = service.GetRootPage();
            if (pages.Length != 0)
            {
                MatchedPage matchedPage = null;
                foreach (string page in pages)
                {
                    matchedPage = current.ChildPages.Match(page);
                    if (matchedPage == null)
                        break;
                    else
                    {
                        current = matchedPage.Page;
                    }
                }
            }

            return current;
        }

        /// <summary>
        /// Initialize the CmsRequestContext
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        protected virtual CmsRequestContext GetCmsRequestContext()
        {
            return CmsRequestContext.Current;
        }

        /// <summary>
        /// Initialize the CmsDataProvider
        /// </summary>
        /// <returns></returns>
        protected virtual ICmsDataProvider GetCmsDataProvider()
        {
            return WebConfiguration.Instance.Provider;
        }
        
    }
}
